﻿using AduSkin.Controls.Metro;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using HsServerHa.Core;
using HsServerHa.Core.Http;
using HsServerHa.Entity.Models;
using HsServerHa.Entity.Models.SqlserverMirror;
using HsServerHa.Utility;
using HsServerHa.Utility.HttpHelper;
using HsServerHa.Utility.SQLite;
using HsServerHa.Utility.SqlserverMirror;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace HsServerHa.UserControls.SqlserverMirrorControls
{
    /// <summary>
    /// SqlServerConnection.xaml 的交互逻辑
    /// </summary>
    public partial class SqlServerConnection : UserControl, INotifyPropertyChanged
    {
        public SqlServerConnection()
        {
            InitializeComponent();
            item.Click += new RoutedEventHandler(item_Click);
            context.Items.Add(item);
            DataBases = new List<DataBaseEntity>();
            this.DataContext = this;

        }

        //ParameterSettings ParameterSettings = new ParameterSettings();

        ContextMenu context = new ContextMenu();
        MenuItem item = new MenuItem();
        bool IsConnection = false;


        // 在用户控件的代码中定义依赖属性
        //public static readonly DependencyProperty UserNameProperty = DependencyProperty.Register("UserName", typeof(string), typeof(SqlServerConnection));

        private string _serverName;

        public string ServerName
        {
            get { return _serverName; }
            set
            {
                _serverName = value;
                OnPropertyChanged("ServerName");
            }
        }
        private string _fontBold;

        public string FontBold
        {
            get { return _fontBold; }
            set
            {
                _fontBold = value;
                OnPropertyChanged("FontBold");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private void SqlServerConnect_Click(object sender, RoutedEventArgs e)
        {
            var DBConnection = ConfigurationManager.AppSettings["DBConnectionString"].ToString();

            var DBConnectionStr = DBConnection.Replace("#IPAddress#", ServerName_TextBox.Text + "," + Port_TextBox.Text);
            DBConnectionStr = DBConnectionStr.Replace("#DBName#", "master");
            DBConnectionStr = DBConnectionStr.Replace("#UserId#", LoginName_TextBox.Text);
            DBConnectionStr = DBConnectionStr.Replace("#UserPwd#", Password.Password);
            //验证主

            var masterConnResult = DbHelperSQL.ConnectionTest(DBConnectionStr);
            if (!masterConnResult)
            {
                AduMessageBox.Show("连接数据库失败，请检查配置");
                return;
            }

            DbHelperSQL db = new DbHelperSQL(DBConnectionStr);
            DataBases = db.Query<DataBaseEntity>($@"SELECT name as Name, 
                create_date as CreateDate, 
                state_desc as StateDesc,
                (CASE dm.mirroring_role
                    WHEN 1 THEN '主体'
                    WHEN 2 THEN '镜像'
                    ELSE '无镜像'
                    END) AS MirroringRoleDesc,
                (CASE dm.mirroring_state
                    WHEN 0 THEN '已挂起'
                    WHEN 1 THEN '与其他伙伴断开'
                    WHEN 2 THEN '正在同步'
                    WHEN 3 THEN '挂起故障转移'
                    WHEN 4 THEN '已同步'
                    WHEN 5 THEN '伙伴未同步'
                    WHEN 6 THEN '伙伴已同步'
                    ELSE '无镜像'
                END) AS MirroringStateDesc
                FROM sys.databases db
                left join sys.database_mirroring dm on db.database_id =  dm.database_id
                where db.name not in ('master','tempdb','model','msdb','distribution')
                order by dm.mirroring_role desc ,Name 
");

            if (this.Name == "LeftConnection")
            {
                ParameterSettings.LeftDataBaseConnection = DBConnectionStr;
                ParameterSettings.LeftServer = ServerName_TextBox.Text;
                ParameterSettings.LeftDataBaseEntitys = DataBases;
                ParameterSettings.LeftPort = Port_TextBox.Text;
                //保存主机服务器信息
                SyncDatabaseServer("Host", ServerName_TextBox.Text, DBConnectionStr, "HOST_1");
            }
            else
            {
                ParameterSettings.RightDataBaseConnection = DBConnectionStr;
                ParameterSettings.RightServer = ServerName_TextBox.Text;
                ParameterSettings.RightDataBaseEntitys = DataBases;
                ParameterSettings.RightPort = Port_TextBox.Text;
                //保存从机服务器信息
                SyncDatabaseServer("Slave", ServerName_TextBox.Text, DBConnectionStr, "HOST_2");
            }

            dbList_DataGrid.ItemsSource = DataBases;
            this.Connect.IsEnabled = false;
            this.DisConnect.IsEnabled = true;
            //this.ResetSqlConfiguration.IsEnabled = true;
            //this.ResetSqlConfiguration.Background =Brushes.Red;
        }

        List<DataBaseEntity> DataBases { get; set; }

        private void dataGrid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)

        {
            if (this.dbList_DataGrid.SelectedItem == null) return;
            OperateType(item);

        }



        private void OperateType(MenuItem item)
        {
            if (dbList_DataGrid.SelectedItem == null) return;
            DataBaseEntity dataBaseEntity = ((DataBaseEntity)dbList_DataGrid.SelectedItem);
            string MirroringRole = dataBaseEntity.MirroringRoleDesc;
            if (this.Name == "RightConnection")
            {
                context.Items.Clear();
                return;
            }

            if (string.IsNullOrEmpty(dataBaseEntity.Operate))
            {
                if (dataBaseEntity.MirroringStateDesc == "与其他伙伴断开")
                {
                    item.Header = "恢复连接";
                    context.IsOpen = true;
                }
                else
                    switch (MirroringRole)
                    {
                        case "主体":
                        case "镜像":
                            item.Header = "删除镜像";
                            context.IsOpen = true;
                            break;
                        case "无镜像":
                            item.Header = "添加镜像";
                            context.IsOpen = true;
                            break;
                    }
            }
            else
            {
                context.IsOpen = true;
                item.Header = "取消操作";
            }


        }

        void item_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(ParameterSettings.LeftDataBaseConnection) || string.IsNullOrEmpty(ParameterSettings.RightDataBaseConnection))
            {
                MessageBox.Show("请同时连接主从数据库后再操作!");
                return;
            }

            DataBaseEntity dataBaseEntity = (DataBaseEntity)dbList_DataGrid.SelectedItem;
            OperateCommandBase operateCommandBase;
            DataBaseEntity otherBaseEntity;
            // do something
            switch (item.Header)
            {
                case "添加镜像":
                    operateCommandBase = new AddMirrorCommand();
                    operateCommandBase.DataBaseName = dataBaseEntity.Name;

                    if (this.Name == "LeftConnection")
                    {
                        operateCommandBase.MainSqlConnectString = ParameterSettings.LeftDataBaseConnection;
                        operateCommandBase.SlaveSqlConnectString = ParameterSettings.RightDataBaseConnection;
                        operateCommandBase.MainServer = ParameterSettings.LeftServer;
                        operateCommandBase.SlaveServer = ParameterSettings.RightServer;
                        operateCommandBase.UserName = LoginName_TextBox.Text;
                        operateCommandBase.Password = Password.Password;
                        operateCommandBase.MainPort = ParameterSettings.LeftPort;
                        operateCommandBase.SlavePort = ParameterSettings.RightPort;

                    }
                    else
                    {
                        operateCommandBase.MainSqlConnectString = ParameterSettings.RightDataBaseConnection;
                        operateCommandBase.SlaveSqlConnectString = ParameterSettings.LeftDataBaseConnection;
                        operateCommandBase.MainServer = ParameterSettings.RightServer;
                        operateCommandBase.SlaveServer = ParameterSettings.LeftServer;
                        operateCommandBase.UserName = LoginName_TextBox.Text;
                        operateCommandBase.Password = Password.Password;
                        operateCommandBase.MainPort = ParameterSettings.LeftPort;
                        operateCommandBase.SlavePort = ParameterSettings.RightPort;
                    }
                    operateCommandBase.UserName = LoginName_TextBox.Text;
                    operateCommandBase.Password = Password.Password;
                    ParameterSettings.OperateCommandBases.Add(operateCommandBase);
                    dataBaseEntity.Operate = item.Header.ToString();
                    break;
                case "删除镜像":
                    operateCommandBase = new DeleteMirrorCommand();
                    operateCommandBase.DataBaseName = dataBaseEntity.Name;

                    if (this.Name == "LeftConnection")
                    {
                        otherBaseEntity = ParameterSettings.RightDataBaseEntitys.FirstOrDefault(s => s.Name == dataBaseEntity.Name);
                        if (otherBaseEntity == null ||
                           otherBaseEntity.MirroringRoleDesc == dataBaseEntity.MirroringRoleDesc ||
                           otherBaseEntity.MirroringRoleDesc == "无镜像" ||
                           otherBaseEntity.MirroringStateDesc != "已同步")
                        {
                            MessageBox.Show("主从数据库不一致，请检查配置");
                            return;
                        }
                        if (otherBaseEntity.MirroringRoleDesc == "主体")
                        {
                            operateCommandBase.MainSqlConnectString = ParameterSettings.LeftDataBaseConnection;
                            operateCommandBase.SlaveSqlConnectString = ParameterSettings.RightDataBaseConnection;
                            operateCommandBase.MainServer = ParameterSettings.LeftServer;
                            operateCommandBase.SlaveServer = ParameterSettings.RightServer;
                            operateCommandBase.MainPort = ParameterSettings.LeftPort;
                            operateCommandBase.SlavePort = ParameterSettings.RightPort;
                        }
                        else
                        {
                            operateCommandBase.MainSqlConnectString = ParameterSettings.RightDataBaseConnection;
                            operateCommandBase.SlaveSqlConnectString = ParameterSettings.LeftDataBaseConnection;
                            operateCommandBase.MainServer = ParameterSettings.RightServer;
                            operateCommandBase.SlaveServer = ParameterSettings.LeftServer;
                            operateCommandBase.MainPort = ParameterSettings.RightPort;
                            operateCommandBase.SlavePort = ParameterSettings.LeftPort;
                        }

                    }
                    else
                    {
                        otherBaseEntity = ParameterSettings.LeftDataBaseEntitys.FirstOrDefault(s => s.Name == dataBaseEntity.Name);
                        if (otherBaseEntity == null ||
                            otherBaseEntity.MirroringRoleDesc == dataBaseEntity.MirroringRoleDesc ||
                            otherBaseEntity.MirroringRoleDesc == "无镜像" ||
                            otherBaseEntity.MirroringStateDesc != "已同步")
                        {
                            MessageBox.Show("主从数据库不一致，请检查配置");
                            return;
                        }
                        if (otherBaseEntity.MirroringRoleDesc == "主体")
                        {
                            operateCommandBase.MainSqlConnectString = ParameterSettings.RightDataBaseConnection;
                            operateCommandBase.SlaveSqlConnectString = ParameterSettings.LeftDataBaseConnection;
                            operateCommandBase.MainServer = ParameterSettings.RightServer;
                            operateCommandBase.SlaveServer = ParameterSettings.LeftServer;
                            operateCommandBase.MainPort = ParameterSettings.RightPort;
                            operateCommandBase.SlavePort = ParameterSettings.LeftPort;

                        }
                        else
                        {
                            operateCommandBase.MainSqlConnectString = ParameterSettings.LeftDataBaseConnection;
                            operateCommandBase.SlaveSqlConnectString = ParameterSettings.RightDataBaseConnection;
                            operateCommandBase.MainServer = ParameterSettings.LeftServer;
                            operateCommandBase.SlaveServer = ParameterSettings.RightServer;
                            operateCommandBase.MainPort = ParameterSettings.LeftPort;
                            operateCommandBase.SlavePort = ParameterSettings.RightPort;
                        }

                    }
                    operateCommandBase.UserName = LoginName_TextBox.Text;
                    operateCommandBase.Password = Password.Password;
                    dataBaseEntity.Operate = otherBaseEntity.Operate = item.Header.ToString();

                    ParameterSettings.OperateCommandBases.Add(operateCommandBase);

                    break;
                case "取消操作":
                    if (ParameterSettings.OperateCommandBases == null) return;
                    if (this.Name == "LeftConnection")
                    {
                        otherBaseEntity = ParameterSettings.RightDataBaseEntitys.FirstOrDefault(s => s.Name == dataBaseEntity.Name);
                    }
                    else
                    {
                        otherBaseEntity = ParameterSettings.LeftDataBaseEntitys.FirstOrDefault(s => s.Name == dataBaseEntity.Name);
                    }
                    ParameterSettings.OperateCommandBases.Remove(ParameterSettings.OperateCommandBases.FirstOrDefault(s => s.DataBaseName == dataBaseEntity.Name));
                    dataBaseEntity.Operate = "";
                    if (otherBaseEntity != null)
                        otherBaseEntity.Operate = "";
                    break;
            }
            if (ParameterSettings.OperateCommandBases.Count > 0)
            {
                WeakReferenceMessenger.Default.Send(new ValueChangedMessage<string>("启用"), "NextButtonIsEnable");
            }
            else
            {
                WeakReferenceMessenger.Default.Send(new ValueChangedMessage<string>("禁用"), "NextButtonIsEnable");
            }

        }

        private void DisConnect_Click(object sender, RoutedEventArgs e)
        {
            dbList_DataGrid.ItemsSource = null;
            this.DataBases.Clear();
            this.Connect.IsEnabled = true;
            this.DisConnect.IsEnabled = false;
        }

        private void Reset_Click(object sender, RoutedEventArgs e)
        {
            dbList_DataGrid.ItemsSource = null;
            this.DataBases.Clear();
            this.LoginName_TextBox.Text = string.Empty;
            this.ServerName_TextBox.Text = string.Empty;
            this.Password.Password = string.Empty;
            this.Connect.IsEnabled = true;
            this.DisConnect.IsEnabled = false;
        }
        /// <summary>
        /// 更新数据库服务器信息
        /// </summary>
        /// <param name="serverType"></param>
        /// <param name="serverIp"></param>
        /// <param name="dbConnectStr"></param>
        /// <param name="hostName"></param>
        private void SyncDatabaseServer(string serverType, string serverIp, string dbConnectStr, string hostName)
        {
            SQLiteHelper.ExecuteSql($"delete from  DatabaseServer where ServerType='{serverType}'");
            var parms = new DatabaseServerEntity
            {
                ProgramKey = GeneratePrimaryKeyIdHelper.GetPrimaryKeyId().ToString(),
                ServerType = serverType,
                ServerIp = serverIp,
                DbConnectStr = dbConnectStr,
                HostName = hostName,
                UpdateTime = DateTime.Now.ToString()
            };
            SQLiteHelper.ExecuteSql($"insert into DatabaseServer (ProgramKey,ServerType,ServerIp,DbConnectStr,HostName,UpdateTime)" +
                                    $" values('{parms.ProgramKey}','{parms.ServerType}','{parms.ServerIp}','{parms.DbConnectStr}','{parms.HostName}','{DateTime.Now.ToString()}')");

        }
        private void ResetSqlConfiguration_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult messageResult = AduMessageBox.ShowOKCancel($"你确定初始化数据库镜像配置吗？该操作会初始化所有的数据库镜像配置，并且主机和从机都需要单独执行该操作", "系统提示!", "确定", "取消");
            if (messageResult == MessageBoxResult.OK)
            {
                //获取数据库镜像列表
                var list = SQLiteHelper.Table<SQLManageEntity>().ToList();
                //获取断开伙伴关系的配置语句
                var checkStatementsEntity = CheckStatementCommand.CheckStatementsEntities.FirstOrDefault(x => x.Id == 25);
                DbHelperSQL dbHelperSQL;
                var SerInfo = new ServiceInfoEntity();

                var dbBackFilePathEntity = SQLiteHelper.Table<DbBackFilePathEntity>().FirstOrDefault();
                //本机
                if (this.Name == "LeftConnection")
                {
                    dbHelperSQL = new DbHelperSQL(ParameterSettings.LeftDataBaseConnection);
                    SerInfo.ServerName = ParameterSettings.LeftServer;
                    SerInfo.DBConnectStr = ParameterSettings.LeftDataBaseConnection;
                    SerInfo.HostName = "HOST_1";
                    CheckStatementCommand.InitDatabaseMirror(SerInfo);

                    //断开伙伴关系
                    if (checkStatementsEntity != null)
                    {
                        if (list != null)
                        {
                            foreach (var item in list)
                            {
                                dbHelperSQL.ExecuteSql(checkStatementsEntity.Statement.Replace("DataBaseName", item.DBName));
                            }
                        }

                    }

                    //删除本地的数据库备份文件和证书
                    string directoryPath = @"D:\dbback"; // 指定要删除的目录路径                                                       
                    try
                    {
                        string[] files = Directory.GetFiles(directoryPath);
                        foreach (string file in files)
                        {
                            File.Delete(file);
                        }
                    }
                    catch (Exception ex)
                    {
                        AduMessageBoxs.Show("删除备份文件报错！请手动删除");
                    }
                }
                else
                {
                    dbHelperSQL = new DbHelperSQL(ParameterSettings.RightDataBaseConnection);
                    SerInfo.DBConnectStr = ParameterSettings.RightDataBaseConnection;
                    SerInfo.ServerName = ParameterSettings.RightServer;
                    SerInfo.HostName = "HOST_2";
                    CheckStatementCommand.InitDatabaseMirror(SerInfo);

                    //断开伙伴关系
                    if (checkStatementsEntity != null)
                    {
                        if (list != null)
                        {
                            foreach (var item in list)
                            {
                                dbHelperSQL.ExecuteSql(checkStatementsEntity.Statement.Replace("DataBaseName", item.DBName));
                            }
                        }

                    }
                    //删除远程的数据库备份文件和证书
                    var slavePath = $"http://{ParameterSettings.RightServer}:{ConfigurationManager.AppSettings["HttpPort"]?.ToString() ?? "6601"}/";
                    var result = HttpHelpers.PostToJson<HttpResponseResultModel<object>>(slavePath +
                   (ConfigurationManager.AppSettings["deleteDbBack"]?.ToString() ?? "deleteDbBack"), JsonConvert.SerializeObject(new ServiceInfoEntity { HostName = "" }));

                }
                //删除配置表数据
                //SQLiteHelper.ExecuteSql($"delete from  SQLManage");
                AduMessageBoxs.Show("初始化数据库镜像配置成功！");
            }

        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            var masterSlaveBindEntity = SQLiteHelper.Table<MasterSlaveBindEntity>().FirstOrDefault();
            if (masterSlaveBindEntity != null)
            {
                if (this.Name == "LeftConnection")
                {
                    this.ServerName_TextBox.Text = masterSlaveBindEntity.MasterIP;
                }
                else
                {
                    this.ServerName_TextBox.Text = masterSlaveBindEntity.SlaveIP;
                }
            }
            var sqlManageEntity = SQLiteHelper.Table<SQLManageEntity>().FirstOrDefault();
            if (sqlManageEntity != null)
            {
                this.LoginName_TextBox.Text = sqlManageEntity.UserId;
                this.Port_TextBox.Text = sqlManageEntity.Port;
                this.Password.Password = sqlManageEntity.UserPwd;
            }

        }
    }
}
